package com.github.maojx0630.easy.translate.translate.impl.dict;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.util.StrUtil;
import com.github.maojx0630.easy.translate.conf.TranslateConfig;
import com.github.maojx0630.easy.translate.select.DictSelect;
import com.github.maojx0630.easy.translate.select.TableSelect;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 毛家兴
 * @since 2024-01-31 16:32
 */
public class ValueCache {

  private final DictSelect dict;

  private final TableSelect table;

  private final Cache<String, String> dictCache;
  private final Cache<String, String> tableCache;

  public ValueCache(DictSelect dict, TableSelect table, TranslateConfig config) {
    this.dict = dict;
    this.table = table;
    switch (config.getCacheType()) {
      case LFU:
        dictCache = CacheUtil.newLFUCache(config.getCacheCapacity(), config.getCacheTime());
        tableCache = CacheUtil.newLFUCache(config.getCacheCapacity(), config.getCacheTime());
        break;
      case LRU:
        dictCache = CacheUtil.newLRUCache(config.getCacheCapacity(), config.getCacheTime());
        tableCache = CacheUtil.newLRUCache(config.getCacheCapacity(), config.getCacheTime());
        break;
      case NOT:
        dictCache = CacheUtil.newNoCache();
        tableCache = CacheUtil.newNoCache();
        break;
      default:
        dictCache = CacheUtil.newTimedCache(config.getCacheTime());
        tableCache = CacheUtil.newTimedCache(config.getCacheTime());
    }
  }

  public String get(String value, TranslateField tf) {

    // 多值情况
    if (StrUtil.isNotBlank(tf.split()) && StrUtil.contains(value, tf.split())) {
      List<String> valueList = StrUtil.split(value, tf.split());
      List<String> selectList = new ArrayList<>();
      for (String s : valueList) {
        String selectValue = getValue(s, tf);
        if (selectValue != null) {
          selectList.add(selectValue);
        }
      }
      if (selectList.isEmpty()) {
        return ifNullSwitch(value, tf);
      }
      if (selectList.size() == 1) {
        return selectList.getFirst();
      }
      if (tf.distinct()) {
        return StrUtil.join(tf.join(), selectList.stream().distinct().collect(Collectors.toList()));
      } else {
        return StrUtil.join(tf.join(), selectList);
      }
    } else {
      // 单值情况
      return getValue(value, tf);
    }
  }

  private String getValue(String value, TranslateField tf) {
    if (StrUtil.isNotBlank(tf.tableName())) {
      String key =
          StrUtil.join("@", tf.tableName(), tf.columnName(), tf.value(), value, tf.remark());
      // 查询table
      return tableCache.get(
          key,
          () -> {
            String selectValue =
                table.selectTable(tf.tableName(), tf.columnName(), tf.value(), value, tf.remark());
            if (selectValue == null) {
              return ifNullSwitch(value, tf);
            } else {
              return selectValue;
            }
          });
    } else {
      String key = StrUtil.join("@", tf.value(), value, tf.remark());
      // 查询dist
      return dictCache.get(
          key,
          () -> {
            String selectValue = dict.selectDict(tf.value(), value, tf.remark());
            if (selectValue == null) {
              return ifNullSwitch(value, tf);
            } else {
              return selectValue;
            }
          });
    }
  }

  private String ifNullSwitch(String value, TranslateField tf) {
    return switch (tf.ifNull()) {
      case EMPTY:
        yield "";
      case NULL:
        yield null;
      case ORIGINAL:
        yield value;
      case OTHER_VALUE:
        yield tf.ifNullValue();
    };
  }

  public void clearDict() {
    dictCache.clear();
  }

  public void clearTable() {
    tableCache.clear();
  }
}
